package com.cangshi.controller;

import com.alibaba.fastjson.JSON;
import com.cangshi.entity.*;
import com.cangshi.service.AddressService;
import com.cangshi.service.UserPlusInfoService;
import com.cangshi.service.UserService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Random;

/**
 * Created by Eoly on 2016/12/22.
 */

@Controller
public class UserController {

    private static final Logger LOGGER = Logger.getLogger(UserController.class);

    @Autowired
    UserService userService;

    @Autowired
    UserPlusInfoService userPlusInfoService;

    @Autowired
    AddressService addressService;


    /**
     * 注册功能
     *
     * @param userRegistion 注册用户实体
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "/register", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String register(@RequestBody UserRegistion userRegistion) {

        JsonObject result = new JsonObject();

//        LOGGER.debug("---------------------------------------------->>>>>>>>>>>" + JSON.toJSON(userRegistion));

        if (userService.getLoginPswByPhoneNumber(userRegistion.getUserPhoneNumber()) == null) {
            result.setError(userService.userRegistered(userRegistion) == 1 ? 0 : 1);
            result.setId(userService.getIdFromLastRegistion());
        } else {
            //101:用户手机号已注册
            result.setError(101);
            result.setMes("该手机号已被注册");
        }

        return JSON.toJSONString(result);
    }

    /**
     * 登陆功能
     *
     * @param userLoginPsw 登录用户实体
     * @param request      用户请求
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "/login", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String login(@RequestBody UserLoginPsw userLoginPsw, HttpServletRequest request) {
        TokenJson result = new TokenJson();

        //验证信息完整性
        if (userLoginPsw.getUserPhoneNumber() != null && userLoginPsw.getUserLoginPsw() != null) {

            UserLoginPsw user;
            if (userLoginPsw.getUserId() != null) //核对密码
                user = userService.getLoginPswByUserId(userLoginPsw.getUserId());
            else
                user = userService.getLoginPswByPhoneNumber(userLoginPsw.getUserPhoneNumber());

            boolean isLogined = user != null && userLoginPsw.getUserLoginPsw().equals(user.getUserLoginPsw());

            //103：账户或密码不正确
            result.setError(isLogined ? 0 : 103);
            result.setMes(isLogined ? "登录成功" : "账户或密码不正确");

            //104：账户被冻结
            if (isLogined && user.getUserStatus() == 1) {
                result.setError(104);
                result.setMes("账户被冻结，登录失败");
            } else if (isLogined && user.getUserStatus() == 0) {
                UserBaseInfo loginUser = userService.getUserBaseInfoByUserId(user.getUserId());
                //登陆成功事件，待添加

                //记录登录信息
                //获取ip地址
                String ip = request.getHeader("x-forwarded-for");
                if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("Proxy-Client-IP");
                }
                if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getHeader("WL-Proxy-Client-IP");
                }
                if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
                    ip = request.getRemoteAddr();
                }
                ip = ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
                LoginInformation loginInformation = new LoginInformation();
                loginInformation.setUserId(loginUser.getUserId());
                loginInformation.setLoginIp(ip);

//                LOGGER.debug("------------------------->"+JSON.toJSON(loginInformation));
                userService.addRecordOfLogin(loginInformation);

                //生产token口令
                String jwtString = Jwts.builder().setSubject(JSON.toJSONString(loginUser))
                        .setIssuedAt(new Date())
                        .signWith(SignatureAlgorithm.HS256, "cangshi").compact();

                //返回token口令
                result.setToken(jwtString);
            }

        } else {
            result.setError(102);
            result.setMes("登录信息不能为空");
        }
        return JSON.toJSONString(result);
    }


    /**
     * 判断用户登陆状态
     *
     * @param request 用户请求
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "/user/isLogin", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String isLogin(HttpServletRequest request) {
        JsonObject<UserBaseInfo> jsonObject = new JsonObject<UserBaseInfo>();
        UserBaseInfo user = (UserBaseInfo) request.getAttribute("user");

        jsonObject.setError((Integer) request.getAttribute("error"));
        jsonObject.setMes((String) request.getAttribute("mes"));
        jsonObject.setData(user);

        return JSON.toJSONString(jsonObject);
    }


    /**
     * 添加用户地址信息
     *
     * @param request 用户请求
     * @param address 地址信息实体
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/add-address", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String addAddress(HttpServletRequest request, @RequestBody Address address) {
        JsonObject jsonObject = new JsonObject();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //封装地址实体用户id
        address.setUserId(userLogin.getUserId());

        //封装添加地址状态和id
        jsonObject.setError(addressService.addAddress(address) == 1 ? 0 : 321);
        jsonObject.setId(addressService.getIdFromLastAdd());

        return JSON.toJSONString(jsonObject);
    }

    /**
     * 显示用户所有的地址信息
     *
     * @param request 用户请求
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/show-address", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String showAddress(HttpServletRequest request) {
        JsonObject<Address> jsonObject = new JsonObject<Address>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");
        List<Address> addresses = addressService.findAddressByUserId(userLogin.getUserId());

        if (addresses != null) {

            jsonObject.setError(0);
            jsonObject.setDataList(addresses);

        } else {
            jsonObject.setError(311);
            jsonObject.setMes("获取失败");
        }

        return JSON.toJSONString(jsonObject);
    }

    /**
     * 删除一个地址信息
     *
     * @param request       用户请求
     * @param address       地址信息实体
     * @param bindingResult 验证完整性结果
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/delete-address", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String deleteAddress(HttpServletRequest request, @Validated @RequestBody Address address, BindingResult bindingResult) {

        JsonObject<Address> jsonObject = new JsonObject<Address>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //验证合法性
        if (bindingResult.hasErrors()) {
            jsonObject.setError(312);
            jsonObject.setMes("地址信息不完整");
        } else if (!userLogin.getUserId().equals(address.getUserId())) {
            jsonObject.setError(313);
            jsonObject.setMes("非法提交");
        } else {
            jsonObject.setError(addressService.deleteAddressByAddressId(address.getAddressId()) == 1 ? 0 : 314);
            jsonObject.setMes(jsonObject.getError() == 0 ? "删除成功" : "删除失败");
        }

        return JSON.toJSONString(jsonObject);
    }

    /**
     * 修改一个地址信息
     *
     * @param request       用户请求
     * @param address       地址信息实体
     * @param bindingResult 验证完整性结果
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/edit-address", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String editAddress(HttpServletRequest request, @Validated @RequestBody Address address, BindingResult bindingResult) {

        JsonObject<Address> jsonObject = new JsonObject<Address>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //验证合法性
        if (bindingResult.hasErrors()) {
            jsonObject.setError(312);
            jsonObject.setMes("地址信息不完整");
        } else if (!userLogin.getUserId().equals(address.getUserId())) {
            jsonObject.setError(313);
            jsonObject.setMes("非法提交");
        } else {
            jsonObject.setError(addressService.updateAddress(address) == 1 ? 0 : 314);
            jsonObject.setMes(jsonObject.getError() == 0 ? "修改成功" : "提交失败");
        }

        return JSON.toJSONString(jsonObject);
    }


    /**
     * 显示用户信息
     *
     * @param request 用户请求
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/show-user-info", method = RequestMethod.GET, produces = "text/html;charset=UTF-8")
    public String showUserInfo(HttpServletRequest request) {

        JsonObject<UserPlusInfo> jsonObject = new JsonObject<UserPlusInfo>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");
        UserPlusInfo userPlusInfo = userPlusInfoService.findUserPlusInfoByUserId(userLogin.getUserId());

        if (userPlusInfo != null) {

            jsonObject.setError(0);
            jsonObject.setData(userPlusInfo);

        } else {
            jsonObject.setError(311);
            jsonObject.setMes("获取失败");
        }

        return JSON.toJSONString(jsonObject);
    }


    /**
     * 修改用户信息
     *
     * @param request       用户请求
     * @param userPlusInfo  地址信息实体
     * @param bindingResult 验证完整性结果
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/edit-user-info", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String editUserInfo(HttpServletRequest request, @Validated @RequestBody UserPlusInfo userPlusInfo, BindingResult bindingResult) {

        JsonObject<UserPlusInfo> jsonObject = new JsonObject<UserPlusInfo>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //验证合法性
        if (bindingResult.hasErrors()) {
            jsonObject.setError(312);
            jsonObject.setMes("用户信息不完整");
        } else if (!userLogin.getUserId().equals(userPlusInfo.getUserId())) {
            jsonObject.setError(313);
            jsonObject.setMes("非法提交");
        } else {
            //电话号码不能修改，此处设置为null意在操作数据库时忽略这一项
            userPlusInfo.setUserPhoneNumber(null);
            jsonObject.setError(userPlusInfoService.updateUserPlusInfo(userPlusInfo) == 1 ? 0 : 314);
            jsonObject.setMes(jsonObject.getError() == 0 ? "修改成功" : "提交失败");
        }

        return JSON.toJSONString(jsonObject);
    }


    /**
     * 用户图片上传入口
     *
     * @param request 用户请求
     * @param image   图片
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/img-upload", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String imgUpload(HttpServletRequest request, @RequestParam MultipartFile image) {
        JsonObject<String> jsonObject = new JsonObject<String>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //获取服务器的路径
        String realPath = request.getSession().getServletContext().getRealPath("/resources/img");

        //声明图片地址
        String imgAddress = null;

        //获取文件名
        String originalFilename = image.getOriginalFilename();

        //获取扩展名
        String extensionName = originalFilename.substring(originalFilename.lastIndexOf('.'));
        System.out.println("--------------->" + extensionName);

        //判断文件格式是否正确
        if (!extensionName.equals(".jpg") && !extensionName.equals(".jpeg") && !extensionName.equals(".png") && !extensionName.equals(".gif")) {

            //返回错误信息
            jsonObject.setError(333);
            jsonObject.setMes("文件格式不正确");

        } else {

            try {
                if (!image.isEmpty()) {

                    //以当前时间加随机数命名上传文件
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmssSSS");
                    String date = sdf.format(new java.util.Date());


                    //设置图片名为当前时间加随机数
                    imgAddress = date + new Random().nextInt() + extensionName;

                    //将文件上传到服务器
                    File f = new File(realPath + "/" + imgAddress);
                    FileUtils.copyInputStreamToFile(image.getInputStream(), f);

                    //设置返回结果
                    jsonObject.setData(imgAddress);
                    jsonObject.setError(0);
                    jsonObject.setMes("上传成功");

                } else {

                    jsonObject.setError(331);
                    jsonObject.setMes("上传的文件不存在");

                }
            } catch (IOException e) {

                jsonObject.setError(332);
                jsonObject.setMes("上传失败");

            }
        }


        return JSON.toJSONString(jsonObject);

    }


    /**
     * 用户图片上传入口
     *
     * @param request 用户请求
     * @param image   图片
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "user/image-upload", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String imageUpload(HttpServletRequest request, @RequestBody String image) {
        JsonObject<String> jsonObject = new JsonObject<String>();

        //获得用户
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //指定头类型
        String header = "data:image/png;base64,";


        //获取服务器的路径
        String realPath = request.getSession().getServletContext().getRealPath("/resources/img");

        //声明图片地址
        String imgAddress = null;

        //获取文件名
        //String originalFilename = image.getOriginalFilename();

        //获取扩展名
        String extensionName = ".png";
        System.out.println("--------------->" + extensionName);

        //判断文件格式是否正确
        if (image == null || image.indexOf(header) != 0) {

            //返回错误信息
            jsonObject.setError(333);
            jsonObject.setMes("文件不存在或格式不正确");

        } else {

            //去掉头部
            image = image.substring(header.length());

            BASE64Decoder decoder = new BASE64Decoder();

            try {
                if (!image.isEmpty()) {

                    //以当前时间加随机数命名上传文件
                    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddhhmmssSSS");
                    String date = sdf.format(new java.util.Date());


                    //设置图片名为当前时间加随机数
                    imgAddress = date + new Random().nextInt() + extensionName;

                    //将文件上传到服务器
                    byte[] decodedBytes = decoder.decodeBuffer(image);

                    FileOutputStream out = new FileOutputStream(realPath + "/" + imgAddress);

                    out.write(decodedBytes);

                    out.close();

                    //设置返回结果
                    jsonObject.setData(imgAddress);
                    jsonObject.setError(0);
                    jsonObject.setMes("上传成功");

                } else {

                    jsonObject.setError(331);
                    jsonObject.setMes("上传的文件不存在");

                }
            } catch (IOException e) {

                jsonObject.setError(332);
                jsonObject.setMes("上传失败");

            }
        }


        return JSON.toJSONString(jsonObject);

    }

    /**
     * 修改用户密码
     *
     * @param request
     * @param pswType
     * @param oldPsw
     * @param newPsw
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "user/modify-psw", method = RequestMethod.POST, produces = "text/html;charset=UTF-8")
    public String modifyPsw(HttpServletRequest request, @RequestParam(required = false) Integer pswType, @RequestParam(required = false) String oldPsw, @RequestParam(required = false) String newPsw) {

        //声明常量
        final int LOGIN_PSW = 0;
        final int PAY_PSW = 1;

        //声明需返回的json对象
        JsonObject jsonObject = new JsonObject();

        //获得用户基本信息
        UserBaseInfo userLogin = (UserBaseInfo) request.getAttribute("user");

        //验证信息完整性
        if (oldPsw == null || newPsw == null) {

            jsonObject.setError(725);
            jsonObject.setMes("未输入旧密码或新密码");
            return JSON.toJSONString(jsonObject);
        }

        //判断指定类型非空
        if (pswType == null) {

            jsonObject.setError(721);
            jsonObject.setMes("请指定修改类型");
            return JSON.toJSONString(jsonObject);
        }

        //获取用户的密码信息
        User checkUser = userService.getUserById(userLogin.getUserId());

        //判断密码类型
        switch (pswType) {

            //修改登录密码
            case LOGIN_PSW: {

                //核对原密码
                if (!oldPsw.equals(checkUser.getUserLoginPsw())) {
                    jsonObject.setError(722);
                    jsonObject.setMes("原登录密码输入错误");
                    return JSON.toJSONString(jsonObject);
                }

                //实例化对象储存新密码
                User newUser = new User();
                newUser.setUserId(userLogin.getUserId());
                newUser.setUserLoginPsw(newPsw);

                //修改密码
                Integer result = userService.modifyUser(newUser);

                if (result != 1) {
                    jsonObject.setError(723);
                    jsonObject.setMes("修改密码失败");
                    return JSON.toJSONString(jsonObject);
                }

                jsonObject.setError(0);
                jsonObject.setMes("修改登录密码成功");

                break;
            }

            //修改支付密码
            case PAY_PSW: {

                //核对原密码
                if (!oldPsw.equals(checkUser.getUserPayPsw())) {
                    jsonObject.setError(722);
                    jsonObject.setMes("原支付密码输入错误");
                    return JSON.toJSONString(jsonObject);
                }

                //实例化对象储存新密码
                User newUser = new User();
                newUser.setUserId(userLogin.getUserId());
                newUser.setUserPayPsw(newPsw);

                //修改密码
                Integer result = userService.modifyUser(newUser);

                if (result != 1) {
                    jsonObject.setError(723);
                    jsonObject.setMes("修改密码失败");
                    return JSON.toJSONString(jsonObject);
                }

                jsonObject.setError(0);
                jsonObject.setMes("修改登录密码成功");

                break;
            }

            default: {
                jsonObject.setError(724);
                jsonObject.setMes("没有指定类型的密码");
            }
        }


        return JSON.toJSONString(jsonObject);
    }

    /**
     * 抛错公共控制器
     *
     * @param request 用户请求
     * @return 结果json
     */
    @ResponseBody
    @RequestMapping(value = "/error", produces = "text/html;charset=UTF-8")
    public String error(HttpServletRequest request) {
        JsonObject jsonObject = new JsonObject();

        jsonObject.setError((Integer) request.getAttribute("error"));
        jsonObject.setMes((String) request.getAttribute("mes"));

//        System.out.println("---------------------->"+(Integer)request.getAttribute("error"));
        return JSON.toJSONString(jsonObject);
    }
}
